/*
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package main;

import gui.GUI;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.EnhancedPatternLayout;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;

import database.ConnectionHandler;
import database.DBConnectionFactory;

/**
 * The main class. Entry point class of the bot
 * 
 * 
 */
public final class Main {
   private static int dbUpdated = 0;
   private final static int BOT_VERSION = 25;
   private final static String RELEASE_VERSION = "2.60";
   private static BotSettings botSettings = null;

   private static void configureLoggers() throws IOException {
	  PatternLayout basicLayout = new PatternLayout("%d - %m%n");
	  DailyRollingFileAppender chat = new DailyRollingFileAppender(basicLayout, System.getProperty("user.dir")
			+ "/chatlogs/chat.log", "'.'yyyy-MM-dd");
	  chat.activateOptions();
	  Logger.getLogger("Chat").addAppender(chat);
	  DailyRollingFileAppender access = new DailyRollingFileAppender(basicLayout, System.getProperty("user.dir")
			+ "/accesslogs/access.log", "'.'yyyy-MM-dd");
	  access.activateOptions();
	  Logger.getLogger("Access").addAppender(access);
	  EnhancedPatternLayout enhancedLayout = new EnhancedPatternLayout("%d %5p (%F:%M:%L) %n%throwable%n");
	  RollingFileAppender error = new RollingFileAppender(enhancedLayout, System.getProperty("user.dir")
			+ "/errorlogs/errors.log");
	  error.activateOptions();
	  ConsoleAppender errorConsole = new ConsoleAppender(enhancedLayout);
	  Logger.getLogger("Error").addAppender(error);
	  Logger.getLogger("Error").addAppender(errorConsole);
   }

   public synchronized static BotSettings getBotSettings() {
	  if (botSettings == null) {
		 botSettings = new BotSettings();
		 new SettingsHandler().loadBotSettings(botSettings);
	  }
	  return botSettings;
   }

   public static int getDbUpdated() {
	  return dbUpdated;
   }

   public static void main(final String[] args) {
	  try {
		 configureLoggers();
	  } catch (IOException ignore) {
	  }
	  setBotAndReleaseVersion();
	  getBotSettings();
	  if (args.length >= 1 && args[0].equals("-no-gui")) {
		 if (dbUpdated > 0) {
			System.out.println(dbUpdated == 1 ? "Database update failed" : "Database was updated. Please restart");
			return;
		 }
		 if (getBotSettings().hasRequiredFields()) {
			if (args.length == 2 && args[1].equals("-new-age")) {
			   DBConnectionFactory.getConnectionHandler().clearForNewAge();
			}
			Bot.getInstance().connectToIRC();
		 } else {
			System.out.println("Bot Settings are incomplete. Shutting down");
		 }
	  } else if (args.length == 5 && args[0].equals("-install")) {
		 if (DBConnectionFactory.getNewInstallHandler(args[1], args[2], args[3], args[4]).runInstall()) {
			System.out.println("Now insert your settings into the database and then run the bot with -no-gui");
		 } else {
			System.out.println("Database creation failed");
		 }
	  } else {
		 new GUI();
	  }
   }

   /**
    * Saves the current bot version
    */
   private static void setBotAndReleaseVersion() {
	  Map<String, String> dbInfo = new SettingsHandler().loadDBSettings();
	  ConnectionHandler handler = DBConnectionFactory.getNewConnectionHandler(dbInfo.get("dbHost"), dbInfo.get("dbName"),
			dbInfo.get("dbUsername"), dbInfo.get("dbPassword"));
	  if (handler == null || handler.getConnection() == null)
		 return;
	  Connection con = handler.getConnection();
	  PreparedStatement ps = null;
	  try {
		 ps = con.prepareStatement("UPDATE version SET botversion = ?, releaseversion = ?");
		 ps.setInt(1, BOT_VERSION);
		 ps.setString(2, RELEASE_VERSION);
		 ps.executeUpdate();

		 if (BOT_VERSION != handler.getDBVersion()) {
			dbUpdated = handler.performDBUpdate();
		 }
	  } catch (final SQLException e) {
		 Logger.getLogger("Error").error("", e);
	  } finally {
		 try {
			ps.close();
		 } catch (final Exception e) {
		 }
		 try {
			con.close();
		 } catch (final Exception e) {
		 }
	  }
   }
}
